今天,我想談?wù)勅绾卧诓煌拇黉N、高峰時(shí)間和突發(fā)的用戶流量期間處理數(shù)百萬(wàn)個(gè)請(qǐng)求。我們談?wù)摰氖钦麄€(gè)平臺(tái)的延遲,您需要記住,系統(tǒng)只與最慢的組件一樣快。對(duì)于最終用戶,如果用戶需要等待幾秒鐘才能看到主頁(yè)上的內(nèi)容,那么您的服務(wù)器有多強(qiáng)大并不重要。此外,請(qǐng)為一些意想不到的問(wèn)題做好準(zhǔn)備,例如如果您沒(méi)有足夠的帶寬來(lái)滿足需求。在這種情況下,無(wú)需尋找應(yīng)用程序本身的問(wèn)題。
讓我們從簡(jiǎn)單的步驟開(kāi)始。一般來(lái)說(shuō),關(guān)注系統(tǒng)性能總是有用的,但也要注意——過(guò)早的優(yōu)化是萬(wàn)惡之源。從了解當(dāng)前應(yīng)用程序中最慢的部分開(kāi)始。
了解什么是慢的
如果您是第一次進(jìn)行優(yōu)化,您可能可以很快識(shí)別出問(wèn)題組件。從在后端和前端拆分我們的應(yīng)用程序開(kāi)始。
默認(rèn)前端優(yōu)化
至于前端,請(qǐng)檢查前端(HTML/js/CSS)的標(biāo)準(zhǔn)緩存實(shí)踐:
- 在響應(yīng)中使用緩存標(biāo)頭(Etag、緩存等)
- 如果可以,將所有靜態(tài)數(shù)據(jù)存儲(chǔ)在 CDN 上
- 使用 tinypng 服務(wù)優(yōu)化您的圖像
- 檢查您的 javascript 庫(kù)。確保您不使用具有相同功能的不同庫(kù)
- Gzip 所有 HTML/js/CSS 內(nèi)容。所有現(xiàn)代瀏覽器都支持 gzipping
- 嘗試減少對(duì) 3rd 方服務(wù)的請(qǐng)求數(shù)量。包括不同的指標(biāo)、分析和廣告工具
簡(jiǎn)單的后端優(yōu)化
至于后端,這里有一個(gè)簡(jiǎn)單的列表,可以幫助您增加應(yīng)用程序響應(yīng)時(shí)間:
- 確保您使用的是數(shù)據(jù)庫(kù)連接池
- 檢查您的 SQL 查詢并為它們添加緩存
- 為整個(gè)響應(yīng)添加緩存
您需要保持緩存更新,但在很多情況下,您可以顯著改善這種情況。
代碼和架構(gòu)發(fā)生了變化
為了更深入,我建議從一些基準(zhǔn)測(cè)試或加載測(cè)試開(kāi)始。根據(jù)您的架構(gòu),您將需要使用不同的工具。使用無(wú)頭 chrome 應(yīng)用程序(testcafe 和類似應(yīng)用程序)進(jìn)行端到端基準(zhǔn)測(cè)試。
基本wrk用法:
wrk -t12 -c400 -d30s http://127.0.0.1:8080/
Running 30s test @ http://127.0.0.1:8080/
12 threads and 400 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 635.91us 0.89ms 12.92ms 93.69%
Req/Sec 56.20k 8.07k 62.00k 86.54%
22464657 requests in 30.00s, 17.76GB read
Requests/sec: 748868.53
Transfer/sec: 606.33MB
測(cè)試最流行的端點(diǎn)并查看總體情況并了解瓶頸所在。
探索細(xì)節(jié)
一旦我們獲得有關(guān)現(xiàn)有瓶頸的信息,我們就需要更深入地挖掘并了解如何解決。在大多數(shù)情況下,最慢的操作是網(wǎng)絡(luò)請(qǐng)求和讀/寫(xiě) I/O 操作。無(wú)論可能 - 嘗試使用非阻塞操作或輕線程進(jìn)行網(wǎng)絡(luò)和 i/o 操作。您可以從使用不同的分析解決方案(如 New Relic 的線程分析器、Stackdriver Profiling 或簡(jiǎn)單地將 pprof 用于 golang/c++ 應(yīng)用程序)中獲得很多好處。
下一步是什么?
在解決了一般瓶頸之后,您可能會(huì)發(fā)現(xiàn)自己已經(jīng)消除了所有主要問(wèn)題,但仍然沒(méi)有您需要的響應(yīng)時(shí)間。您可以采取的下一步是更新應(yīng)用程序架構(gòu),設(shè)置具有自動(dòng)縮放功能的 Kubernetes,并開(kāi)始使用云提供商。
微服務(wù)
典型情況 - 當(dāng)您有幾個(gè)組件在高峰時(shí)間消耗 80% 的資源時(shí)。這兩個(gè)組件核心功能的原因是運(yùn)行速度不夠快并且項(xiàng)目失去了用戶。一個(gè)可靠且強(qiáng)大的解決方案是按部分拆分您的應(yīng)用程序,這樣每個(gè)部分都可以獨(dú)立工作并僅在需要的地方添加資源。使用微服務(wù),您可以歸檔:
- 通過(guò)模塊化更好地管理
- 大規(guī)模部署和更新軟件
使用 Kubernetes 和自動(dòng)縮放
可能,如果您還沒(méi)有,您應(yīng)該開(kāi)始使用 Kubernetes。它確實(shí)使您能夠在需要時(shí)添加更多資源,并在選擇消失后將其關(guān)閉。K8s 提供了很好的、經(jīng)過(guò)良好測(cè)試的容器編排解決方案,并添加了容錯(cuò)更新,具有跨集群的內(nèi)置通信等等。但缺點(diǎn)之一是維護(hù)起來(lái)既困難又費(fèi)時(shí)。
使用云提供商
AWS、谷歌云、Azure——這些都是很棒的解決方案,它們將為您提供和管理先進(jìn)的技術(shù)。雖然您將為所有這些花里胡哨的東西付出更多,但其中一些有助于輕松構(gòu)建可擴(kuò)展、可靠的解決方案。如果您預(yù)計(jì)每秒有數(shù)百萬(wàn)個(gè)請(qǐng)求,那么您可能應(yīng)該從一開(kāi)始就考慮使用云提供商。